接續實作-商品系統(四)-訂單列表及訂購商品部分(二),我們將繼續完成訂單列表及訂購商品部分
的開發。
新增的部分:
.
├── app.js
├── bin
│ └── www
├── config
│ └── development_config.js
├── controllers
│ ├── member
│ │ └── modify_controller.js
│ ├── order
│ │ ├── get_controller.js
│ │ └── modify_controller.js
│ ├── product
│ │ └── get_controller.js
├── models
│ ├── member
│ │ ├── encryption_model.js
│ │ ├── login_model.js
│ │ ├── register_model.js
│ │ ├── update_model.js
│ │ └── verifyication_model.js
│ ├── order
│ │ ├── all_order_model.js
│ │ ├── delete_model.js
│ │ ├── one_order_model.js
│ │ ├── order_all_product_model.js
│ │ ├── order_one_product_model.js
│ │ └── update_model.js
│ ├── product
│ │ └── all_product.js
│ └── connection_db.js
├── package.json
├── public
│ ├── images
│ ├── javascripts
│ └── stylesheets
│ └── style.css
├── routes
│ ├── member.js
│ ├── order.js
│ └── product.js
├── sevice
│ └── member_check.js
├── views
├── error.ejs
└── index.ejs
├── .env
└── .gitignore
筆者將這支API預設為client端需要輸入的資料為兩種情況,分別是:
那要怎麼透過程式來區分到底會員再進行刪除動作時,其結果是「刪除單筆」還是「刪除多筆」呢?這部分我們可藉由資料重整的方式來處理。
若要讓資料庫進行刪除訂單資料的動作是需要order_id
、member_id
及product_id
這三個欄位的值,才能準確的刪除我們所想要刪除的資料。等同於說我們預期資料應該要整理成像下述的樣子才能啟用SQL query
。
orderID = 1, memberID = 1, productID = 1
在JavaScript語系中,我們只要把資料整理成像下述那樣,就能處理這情況。
[ { orderID: '1', memberID: 1, productID: '1' } ]
[ { orderID: '1', memberID: 1, productID: '1' },
{ orderID: '1', memberID: 1, productID: '2' } ]
另外,我們依舊需要先判定欲刪除的這筆訂單是否存在及是否已經完成付款動作了。而這部分會繼續沿用在實作-商品系統(五)-修改訂單部分(一)中所寫的兩個判斷:
const checkOrderData = function (orderID, memberID, productID) {
return new Promise((resolve, reject) => {
db.query('SELECT * FROM order_list WHERE order_id = ? AND member_id = ? AND product_id = ?', [orderID, memberID, productID], function (err, rows) {
if (rows[0] === undefined) {
resolve(false);
} else {
resolve(true);
}
})
})
}
const checkOrderComplete = function (orderID, memberID, productID) {
return new Promise((resolve, reject) => {
db.query('SELECT * FROM order_list WHERE order_id = ? AND member_id = ? AND product_id = ? AND is_complete = 0', [orderID, memberID, productID], function (err, rows) {
if (rows[0] === undefined) {
resolve(false);
} else {
resolve(true);
}
})
})
}
至models
> order
資料夾的delete_model.js
檔案中寫入:
const db = require('../connection_db');
module.exports = function orderDelete(deleteList) {
return new Promise(async (resolve, reject) => {
let result = {};
// 有幾筆資料就刪除幾次資料
for (let key in deleteList) {
let hasData = await checkOrderData(deleteList[key].orderID, deleteList[key].memberID, deleteList[key].productID);
let hasComplete = await checkOrderComplete(deleteList[key].orderID, deleteList[key].memberID, deleteList[key].productID);
if (hasData === false) {
result.status = "刪除訂單資料失敗。"
result.err = "找不到該筆資料。"
reject(result);
}
else if (hasComplete === false) {
result.status = "刪除訂單資料失敗。"
result.err = "該筆資料已經完成。"
reject(result);
} else if (hasData === true && hasComplete === true) {
db.query('DELETE FROM order_list WHERE order_id = ? and member_id = ? and product_id = ?', [deleteList[key].orderID, deleteList[key].memberID, deleteList[key].productID], function (err, rows) {
if (err) {
console.log(err);
result.err = "伺服器錯誤,請稍後在試!"
reject(result);
return;
}
result.status = "刪除訂單資料成功。";
result.deleteList = deleteList;
resolve(result);
});
}
}
})
}
之後,將model
匯入controllers
> order
資料夾的modify_controller.js
中並寫入個deleteOrderProduct
的function。
deleteOrderProduct(req, res, next) {
const token = req.headers['token'];
//確定token是否有輸入
if (check.checkNull(token) === true) {
res.json({
err: "請輸入token!"
})
} else if (check.checkNull(token) === false) {
verify(token).then(tokenResult => {
if (tokenResult === false) {
res.json({
result: {
status: "token錯誤。",
err: "請重新登入。"
}
})
} else {
// 取得欲刪除的資料
const orderID = req.body.orderID;
const memberID = tokenResult;
// 防呆處理,去處空白
const productID = req.body.productID.replace(" ", "");
const splitProductID = productID.split(",");
let deleteList = [];
// 重整成資料庫可辨識的順序
for (let i = 0; i < splitProductID.length; i += 1) {
deleteList.push({orderID: orderID, memberID: memberID, productID: splitProductID[i]});
}
deleteOrderData(deleteList).then(result => {
res.json({
result: result
})
}, (err) => {
res.json({
result: err
})
})
}
})
}
}
最後,再給予這個API一個URL。至routes
資料夾的order.js
檔案中寫入:
var express = require('express');
var router = express.Router();
const OrderGetMethod = require('../controllers/order/get_controller');
const OrderModifyMethod = require('../controllers/order/modify_controller');
orderGetMethod = new OrderGetMethod();
orderModifyMethod = new OrderModifyMethod();
// 取得全部訂單資料
router.get('/order', orderGetMethod.getAllOrder);
// 取得單一顧客的訂單資料
router.get('/order/member', orderGetMethod.getOneOrder);
// 訂整筆訂單
router.post('/order', orderModifyMethod.postOrderAllProduct);
// 更改單筆訂單資料
router.put('/order', orderModifyMethod.updateOrderProduct);
// 刪除訂單資料
router.delete('/order', orderModifyMethod.deleteOrderProduct);
module.exports = router;
假設目前order_list
的table中有五筆資料:
我們用訂單2的資料來測試多筆刪除,訂單3則用來測試單筆刪除。
x-www-form-urlencoded
其結果:
MySQL那邊的結果:
x-www-form-urlencoded
其結果:
MySQL那邊的結果:
筆者將這支API預設為client端需要輸入的資料為:
也就是需要輸入特定訂單的編號,要額外新增的商品編號及其數量。但在實作前我們必須要做兩件事情,分別是:
product
的table撈取特定商品的價格。先至models
> order
資料夾的order_one_product_model.js
檔案來進行撰寫:
這部分我們一樣拿先前確認訂單資料的function來做判斷:
const checkOrderData = (orderID, memberID, productID) => {
return new Promise((resolve, reject) => {
db.query('SELECT * FROM order_list WHERE order_id = ? AND member_id = ? AND product_id = ?', [orderID, memberID, productID], function (err, rows) {
if (rows[0] === undefined) {
resolve(false);
} else {
resolve(true);
}
})
})
}
但這部分的做法有別於之前都是用來確認是有該訂單的,而是用來確認是沒有該筆訂單才能進行新增單筆訂單資料的動作。
const checkOrderComplete = (orderID) => {
return new Promise((resolve, reject) => {
db.query('SELECT is_complete FROM order_list WHERE order_id = ?', orderID, function (err, rows) {
if (rows[0].is_complete === 1) {
resolve(false);
} else {
resolve(true);
}
})
})
}
const getProductPrice = (productID) => {
return new Promise((resolve, reject) => {
db.query('SELECT price FROM product WHERE id = ?', productID, function (err, rows) {
if (err) {
console.log(err);
reject(err);
return;
}
resolve(rows[0].price);
})
})
}
const db = require('../connection_db');
module.exports = function postOneOrderData(orderOneList) {
let result = {};
return new Promise(async (resolve, reject) => {
const hasData = await checkOrderData(orderOneList.orderID, orderOneList.memberID, orderOneList.productID);
const hasComplete = await checkOrderComplete(orderOneList.orderID);
if (hasData === true) {
result.status = "新增單筆訂單資料失敗。"
result.err = "已有該筆訂單資料!"
reject(result)
} else if (hasComplete === false){
result.status = "新增單筆訂單資料失敗。"
result.err = "該筆訂單已經完成。"
reject(result)
} else if (hasData === false) {
const price = await getProductPrice(orderOneList.productID);
const orderList = {
order_id: orderOneList.orderID,
member_id: orderOneList.memberID,
product_id: orderOneList.productID,
order_quantity: orderOneList.quantity,
order_price: orderOneList.quantity * price,
is_complete: 0,
order_date: orderOneList.createDate
}
db.query('INSERT INTO order_list SET ?', orderList, function (err, rows) {
// 若資料庫部分出現問題,則回傳「伺服器錯誤,請稍後再試!」的結果。
if (err) {
console.log(err);
result.status = "新增單筆訂單資料失敗。"
result.err = "伺服器錯誤,請稍後在試!"
reject(result);
return;
}
result.status = "新增單筆訂單資料成功。"
result.orderList = orderList
resolve(result);
})
}
})
}
再來將model
的部分匯入controllers
> order
資料夾的modify_controller.js
檔案,並放置在postOrderOneProduct
的function中:
postOrderOneProduct(req, res, next) {
const token = req.headers['token'];
//確定token是否有輸入
if (check.checkNull(token) === true) {
res.json({
err: "請輸入token!"
})
} else if (check.checkNull(token) === false) {
verify(token).then(tokenResult => {
if (tokenResult === false) {
res.json({
result: {
status: "token錯誤。",
err: "請重新登入。"
}
})
} else {
// 提取要新增的單筆資料
const memberID = tokenResult;
const orderOneList = {
orderID: req.body.orderID,
memberID: memberID,
productID: req.body.productID,
quantity: req.body.quantity,
createDate: onTime()
}
orderOneProductData(orderOneList).then(result => {
res.json({
result: result
})
}, (err) => {
res.json({
result: err
})
})
}
})
}
}
最後,給予這個API一個URL。至routes
資料夾的order.js
檔案中寫入:
var express = require('express');
var router = express.Router();
const OrderGetMethod = require('../controllers/order/get_controller');
const OrderModifyMethod = require('../controllers/order/modify_controller');
orderGetMethod = new OrderGetMethod();
orderModifyMethod = new OrderModifyMethod();
// 取得全部訂單資料
router.get('/order', orderGetMethod.getAllOrder);
// 取得單一顧客的訂單資料
router.get('/order/member', orderGetMethod.getOneOrder);
// 訂整筆訂單
router.post('/order', orderModifyMethod.postOrderAllProduct);
// 更改單筆訂單資料
router.put('/order', orderModifyMethod.updateOrderProduct);
// 刪除訂單資料
router.delete('/order', orderModifyMethod.deleteOrderProduct);
// 訂單筆訂單
router.post('/order/addoneproduct', orderModifyMethod.postOrderOneProduct);
module.exports = router;
這部分我們使用Postman來進行測試:
HTTP method: POST
HTTP url : localhost:3000/order/addoneproduct
Body中選擇x-www-form-urlencoded
headers
body
測試結果為:
MySQL的狀況為:
在這階段我們已經完成修改訂單部分
的四支API,而下個章節將接續開發確認訂單部分
的功能。